<?php

namespace service\file;

use service\file\File;

/**
 * 基于thinkphp 5.0的 File.php 处理
 */
class HttpUpload
{
    protected $file, $uploaded, $save_path, $errors;

    /**
     * __construct
     *
     * @param string $path
     * @return void
     */
    public function __construct($path = null)
    {
        $path !== null and $this->setSavePath($path);
    }

    /**
     * setSavePath
     *
     * @param string $path
     * @return string|null
     */
    public function setSavePath($path)
    {
        return $this->save_path = $path;
    }

    /**
     * getSavePath
     *
     * @param string $path
     * @return string|null
     */
    public function getSavePath()
    {
        return $this->save_path;
    }

    /**
     * http $_FILES handler
     *
     * @param  string $name
     * @return array
     */
    public function file($name = '')
    {
        if (empty($this->file)) {
            $this->file = isset($_FILES) ? $_FILES : [];
        }
        if (is_array($name)) {
            return $this->file = array_merge($this->file, $name);
        }
        $files = $this->file;
        if (!empty($files)) {
            // 处理上传文件
            $array = [];
            foreach ($files as $key => $file) {
                if (is_array($file['name'])) {
                    $item = [];
                    $keys = array_keys($file);
                    $count = count($file['name']);
                    for ($i = 0; $i < $count; $i++) {
                        if (empty($file['tmp_name'][$i])) {
                            continue;
                        }
                        $temp['key'] = $key;
                        foreach ($keys as $_key) {
                            $temp[$_key] = $file[$_key][$i];
                        }
                        $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);
                    }
                    $array[$key] = $item;
                } else {
                    if ($file instanceof File) {
                        $array[$key] = $file;
                    } else {
                        if (empty($file['tmp_name'])) {
                            $this->setError($file, $key);
                            continue;
                        }
                        $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);
                    }
                }
            }
            if (strpos($name, '.')) {
                list($name, $sub) = explode('.', $name);
            }
            $this->uploaded = $array;
            if ('' === $name) {
                // 获取全部文件
                return $array;
            } elseif (isset($sub) && isset($array[$name][$sub])) {
                return $array[$name][$sub];
            } elseif (isset($array[$name])) {
                return $array[$name];
            }
        }
        $this->setError('no file was founded');
        return null;
    }

    /**
     * upload handler
     *
     * @param  string  $name
     * @param  string  $save_path
     * @return array|boolean
     */
    public function upload($name = '', $save_path = null)
    {
        $files = $this->file($name);
        if (!is_array($files)) {
            if ($files instanceof File) {
                $files = [$files];
            } else {
                $this->setError('no file was uploaded');
                return false;
            }
        }
        $files = $this->moveFiles($files, $save_path ?: $this->getSavePath());
        return $files;
    }

    /**
     * moveFiles
     *
     * @param  array  $files
     * @param  string $save_path
     * @return array|boolean
     */
    protected function moveFiles(array $files, $save_path = null)
    {
        $save_path === null and $save_path = $this->getSavePath();
        if (!is_dir($save_path) && !mkdir($save_path, 0755, true)) {
            $this->setError($save_path . ' doesnt exists, and cannot create this dir automaticly');
            return false;
        }
        $tmps = [];
        foreach ($files as $key => $file) {
            if (is_array($file)) {
                $tmps[$key] = $this->moveFiles($file, $save_path);
            } elseif ($file instanceof File) {
                if(!($tmps[$key] = $file->move($save_path))){
                    $this->setError($file->getError(), $key);
                    return false;
                }
            }
        }
        return $tmps;
    }

    /**
     * setError
     *
     * @param string $error
     * @param string $key
     * @return mixed
     */
    protected function setError($error, $key = null)
    {
        if (!$error) {
            return false;
        }
        if (!is_string($key) || !trim($key)) {
            $key = microtime(true);
        }
        return $this->errors[$key] = $error;
    }

    /**
     * getError
     *
     * @return array
     */
    public function getError()
    {
        return $this->errors;
    }
}
